/*************************************************************************
 *************************************************************************
 	 	 	 	 	 	 	M2SMA : SDLAgent.cpp
 *************************************************************************
 *
 	 Copyright (C) 2011
 	TODO, Steven Costiou, France
 *
 **************************************************************************
 **************************************************************************
 *
	FILE COMMENT /// TODO
 *
 **************************************************************************
 **************************************************************************
 *
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/
 *
 **************************************************************************
 **************************************************************************/

#include "SDLAgent.h"
#include "GameEngine.h"

SDLAgent::SDLAgent(Engine* parentEngine) : Agent(parentEngine)
{
	addClassName("SDL_AGENT");

	agentStarted = false;

	SCREEN_WIDTH = 640;
	SCREEN_HEIGHT = 480;
	SCREEN_BPP = 32;

	screen = NULL;

	bounds = new SDL_Rect;
	bounds->w = SCREEN_WIDTH;
	bounds->h = SCREEN_HEIGHT;
	bounds->x = 0;
	bounds->y =0;

	toDisplayList = new vector<SDL_Rect*>();

	registeredAgents = 0;
	registeredAgentsForDisplay = new map<unsigned long int, DWGraphicAgent*>();

	startAgent();
}

SDLAgent::~SDLAgent()
{
	delete bounds;
}

bool SDLAgent::initialize()
{
    /**
     * SDL subsystems initialization.
     */
    if(SDL_Init(SDL_INIT_EVERYTHING) == -1)
    {
        return false;
    }

    /**
     * Setting the screen up.
     */
    screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE/*SDL_DOUBLEBUF*/);

    if(screen == NULL)
    {
        return false;
    }

    /**
     * Setting the name of the window.
     */
    SDL_WM_SetCaption( "SDL_AGENT RUNNING...", NULL );

   return true;
}

void SDLAgent::clean_up()
{
    SDL_Quit();
    this->stopSystem();
}

void SDLAgent::startAgent()
{

	if(initialize() == false)
	{
		/// TODO Raise an exception here ?
		cout << "SDL initialization failed." << endl;
	}

	SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0, 0, 0));
}

void SDLAgent::displayWhiteRectangle(SDL_Rect* anSDLRectangle)
{
	toDisplayList->push_back(anSDLRectangle);
}

unsigned long int SDLAgent::registerAgentForDisplay(DWGraphicAgent* aDWGraphicAgent)
{
	registeredAgents += 1;
	registeredAgentsForDisplay->insert(pair<unsigned long int, DWGraphicAgent*> (registeredAgents, aDWGraphicAgent));

	return registeredAgents;
}

void SDLAgent::live()
{
	if(!agentStarted)
		startAgent();

	cout << "This is SDL Agent : " << this->getName() << endl;

	while(SDL_PollEvent(&event))
	{
		if(event.type == SDL_QUIT)
		{
			clean_up();
		}
	}

	toDisplayObjectIterator = toDisplayList->begin();

	for(toDisplayObjectIterator = toDisplayList->begin(); toDisplayObjectIterator != toDisplayList->end(); toDisplayObjectIterator++)
		SDL_FillRect(screen, *toDisplayObjectIterator, SDL_MapRGB(screen->format, 255, 255, 255));

	SDL_Rect* coordinates;
	SDL_Surface* surface;

	toDisplayGraphicsObjectIterator = registeredAgentsForDisplay->begin();
	for(toDisplayGraphicsObjectIterator = registeredAgentsForDisplay->begin(); toDisplayGraphicsObjectIterator != registeredAgentsForDisplay->end(); toDisplayGraphicsObjectIterator++)
	{
		coordinates = (*toDisplayGraphicsObjectIterator).second->getCoordinates();
		surface = (*toDisplayGraphicsObjectIterator).second->getCurrentGraphics();

		coordinates->h = surface->h;
		coordinates->w = surface->w;

		 SDL_BlitSurface(surface, NULL, screen, coordinates);
	}

	SDL_Flip(screen);

	toDisplayList->clear();
}
